26.2 Die Verbindung zu einer Datenquelle herstellen
 
Wollen Sie aus einer Anwendung heraus auf eine Datenbank zugreifen, ist die erste zu treffende Entscheidung die des eingesetzten Datenproviders. Für die providerspezifischen Klassen ist jeweils ein separater Namespace in der .NET-Klassenbibliothek vorgesehen. Thema dieses Abschnitts ist der Aufbau einer Verbindung zum SQL Server unter Einsatz des SqlClient-Datenproviders. Daher sollten Sie mit
| using System.Data.SqlClient;
|
den entsprechenden Namespace zuerst bekannt geben.
Die Verbindung zu einer Datenbank wird durch ein Connection-Objekt beschrieben. Um präzise zu sein, gibt es die Klasse Connection unter ADO.NET nicht. Stattdessen wird, abhängig vom verwendeten .NET-Datenprovider, ein Präfix vorangestellt. Benutzen Sie den SqlClient-Datenprovider, heißt die Klasse SqlConnection, beim OleDb-Datenprovider OleDbConnection.
Um auf eine Datenquelle wie dem Microsoft SQL Server zuzugreifen, werden mehrere Informationen benötigt:
|
der Name des Rechners, auf dem die SQL Server-Instanz läuft |
|
der Name der Datenbank, deren Dateninformationen ausgewertet oder manipuliert werden sollen |
|
Anmeldeinformationen, mit denen sich der Anwender authentifiziert |
Diese Verbindungsinformationen werden nach einem bestimmten Muster in einer Zeichenfolge zusammengefasst, die als Verbindungszeichenfolge bezeichnet wird. Grundsätzlich haben Sie zwei Möglichkeiten, die Verbindungsinformationen zu einer Datenquelle anzugeben:
|
Sie rufen den parameterlosen Konstruktor der Connection-Klasse auf und übergeben der Eigenschaft ConnectionString des erzeugten Objekts die Verbindungsinformationen. |
|
Sie rufen einen parametrisierten Konstruktor auf. |
Sehen wir uns zuerst den Verbindungsaufbau mit dem parameterlosen Konstruktor an.
| SqlConnection con = new SqlConnection();
|
Damit erzeugen wir bereits das Verbindungsobjekt, das aber noch sehr dumm ist, da ihm sämtliche Informationen fehlen, die zum Aufbau der Verbindung zu einer Datenquelle notwendig sind. Diese müssen der Eigenschaft ConnectionString des Connection-Objekts zugewiesen werden:
| SqlConnection con = new SqlConnection();
|
| con.ConnectionString = "<Verbindungszeichenfolge>";
|
Der parametrisierte Konstruktor gestattet es, die Verbindungszeichenfolge als Argument zu übergeben.
| SqlConnection con = new SqlConnection("<Verbindungszeichenfolge>");
|
26.2.1 Der Inhalt der Verbindungszeichenfolge
 
Alle Informationen, die zum Aufbau einer Verbindung zu einer Datenquelle erforderlich sind, werden in der Verbindungszeichenfolge beschrieben. Eine Verbindungszeichenfolge besteht aus einer Reihe von Attributen, denen Werte zugewiesen werden. Die Attribute sind untereinander durch ein Semikolon getrennt. Die allgemeine Syntax lässt sich wie folgt beschreiben:
| string strCon = "Attribut1=Wert1;Attribut2=Wert2;Attribut3=Wert3;...";
|
Die Bezeichner der einzelnen Attribute sind festgelegt und hängen vom verwendeten .NET-Datenprovider ab. In der folgenden Tabelle sind die des SqlClient-Datenproviders aufgeführt. Die Groß-/Kleinschreibung spielt dabei ebenso wenig eine Rolle wie die Reihenfolge der Attribute. Beachten Sie, dass es meistens mehrere Attributbezeichner gibt, die gleichwertig benutzt werden können.
Tabelle 26.1 Attribute der Verbindungszeichenfolge des SQL-Datenproviders
| Schlüssel
|
Beschreibung
|
| Connect Timeout, Connection Timeout
|
Dieser Schlüssel beschreibt die Zeitdauer in Sekunden, die auf eine Verbindung zum Server gewartet werden soll, bevor der Versuch abgebrochen und ein Fehler generiert wird. Der Standardwert beträgt 15 Sekunden.
|
| Data Source, Server, Address, Addr, Network Address
|
Entweder der Name oder die Netzwerkadresse der Instanz des SQL Servers, mit dem eine Verbindung hergestellt werden soll.
|
| Initial Catalog, Database
|
Hier wird der Name der Datenbank angegeben.
|
| Integrated Security, Trusted_Connection
|
Bei false werden die Benutzer-ID und das Kennwort für die Verbindung angegeben. Bei true werden die aktuellen Anmeldeinformationen des Windows-Kontos für die Authentifizierung verwendet. Gültige Werte sind true, false, yes, no und sspi, das äquivalent zu true ist. Die .NET-Dokumentation empfiehlt, sspi zu benutzen.
|
| Packet Size
|
Gibt die Größe der Netzwerkpakete in Byte an, die zum Kommunizieren mit einer Instanz von SQL Server verwendet werden. Die Standardgröße eines Pakets beträgt 8192 Byte, kann aber zwischen 512 und 32767 variieren.
|
| Password, Pwd
|
Das Kennwort für das SQL Server-Konto.
|
| User ID
|
Das SQL Server-Anmeldekonto.
|
| Workstation ID
|
Der Name des Computers, der mit dem SQL Server eine Verbindung aufbauen möchte
|
Beabsichtigen Sie, auf den lokal installierten SQL Server und dessen Beispieldatenbank pubs zuzugreifen, könnte die Verbindungszeichenfolge wie folgt lauten:
| SqlConnection con = new SqlConnection();
|
| con.ConnectionString = "Data Source=(local);" +
|
| "Initial Catalog=pubs;" +
|
| "Trusted_Connection=yes";
|
Data Source beschreibt den Namen des Rechners, auf dem sich die laufende SQL Server-Instanz befindet. Handelt es sich dabei um den lokalen Rechner, dürfen Sie anstatt des Rechnernamens auch (local), localhost oder einfach nur einen Punkt angeben – die beiden letztgenannten allerdings ohne runde Klammern. Hinter Initial Catalog ist die Datenbank angegeben, zum Schluss folgen noch Informationen zur Authentifizierung.
| Hinweis Setzen Sie in der Verbindungszeichenfolge keine unnötigen Leerzeichen, auch wenn das aus Ihrer Sicht die Lesbarkeit verbessert. Der .NET-Datenprovider wird nämlich versuchen, die Leerzeichen zu interpretieren mit der Folge, dass ein Laufzeitfehler auftritt, weil beispielsweise der Rechner oder die Datenbank nicht gefunden werden.
|
Sie müssen nicht zwangsläufig alle Attribute verwenden. Das Attribut Packet Size wird oben beispielsweise nicht verwendet. Somit werden alle Daten auf der Verbindung in 8192 Byte großen Paketen verschickt. Müssen große Datenmengen vom Server geladen werden, z.B. Bilder, können größere Pakete die Leistung durchaus deutlich steigern.
26.2.2 Die Authentifizierung
 
Soll die Verbindung zu einer Datenbank aufgebaut werden, muss sich der Anwender bei der Datenbank einloggen. Das Connection-Objekt benutzt hierfür die Authentifizierungsinformationen, die in der Verbindungszeichenfolge enthalten sind. Diese werden vom Datenbankserver überprüft.
Der SQL Server kennt zwei Verfahren zur Authentifizierung:
|
die integrierte Windows-Authentifizierung |
|
die SQL Server-Authentifizierung |
Bei der integrierten Windows-Authentifizierung muss weder ein Benutzername noch ein Passwort explizit gesendet werden. Mit der Angabe von Trusted_Connection=yes verwendet das System automatisch das Windows-Benutzerkonto des aktuellen Users bestehend aus Benutzername und Passwort und reicht es an den SQL Server weiter. Vorausgesetzt der Kontoinhaber hat ausreichende Rechte, wird eine Verbindung zur Datenbank hergestellt.
Die SQL Server-Authentifizierung setzt voraus, dass der Administrator des SQL Servers ein Benutzerkonto mit Passwort eingerichtet hat. Sowohl der Benutzername als auch das Passwort müssen bei diesem Authentifizierungsverfahren in der Verbindungszeichenfolge stehen, z.B.:
| SqlConnection con = new SqlConnection();
|
| con.ConnectionString = "Data Source=DBServer;" +
|
| "Initial Catalog=pubs;" +
|
| "User ID=Testuser;" +
|
| "Password=26gf28";
|
Der SQL Server führt die Authentifizierung durch, indem er überprüft, ob ein SQL Server-Anmeldekonto mit diesem Namen eingerichtet ist und ob das angegebene Kennwort stimmt. Falls die übermittelten Anmeldeinformationen falsch sind, misslingt die Authentifizierung, und der Benutzer erhält eine Fehlermeldung.
Es ist grundsätzlich nicht empfehlenswert, die Daten zur Benutzerauthentifizierung in der Verbindungszeichenfolge zu speichern. Besser ist es, den Anwender zur Eingabe von Benutzernamen und Passwort aufzufordern und mit diesen Informationen zur Laufzeit die Verbindungszeichenfolge zu bilden.
26.2.3 Das Öffnen einer Verbindung
 
Das Instanziieren der Klasse SqlConnection und die Bekanntgabe der Verbindungszeichenfolge sind noch nicht ausreichend, um die Verbindung zu einer Datenbank tatsächlich zu öffnen und auf die in ihr enthaltenen Daten zuzugreifen. Dazu muss noch die Methode Open auf das Connection-Objekt aufgerufen werden:
Weist die Verbindungszeichenfolge keinen Fehler auf, könnten Sie nun auf die Daten von pubs zugreifen. Es gibt allerdings eine Reihe potenzieller Fehlerquellen, die zu einem Laufzeitfehler beim Verbindungsaufbau führen können:
|
Ein Fehler in der Verbindungszeichenfolge |
|
Der Anwender hat keine Zugriffsrechte auf die Datenbank. |
|
Der SQL Server ist nicht gestartet. |
|
Der Rechner, auf dem die SQL Server-Instanz läuft, ist im Netzwerk nicht erreichbar. |
Sie sollten daher das Öffnen einer Datenbankverbindung immer in einen Fehlerbehandlungsblock einschließen.
| try {
|
| SqlConnection con = new SqlConnection("Data Source=localhost;" +
|
| "Initial Catalog=pubs;Trusted_Connection=yes");
|
| con.Open();
|
| }
|
| catch(Exception e) {
|
| // Anweisungen
|
| }
|
26.2.4 Schließen einer Verbindung
 
Man könnte der Meinung sein, dass eine geöffnete Verbindung geschlossen wird, wenn das Connection-Objekt aufgegeben wird. Das wäre zum Beispiel der Fall, wenn die Referenz des Connection-Objekts auf null gesetzt wird oder die Objektvariable ihren Gültigkeitsbereich verlässt. Das stimmt aber nur aus Sicht des zugreifenden Prozesses, denn tatsächlich werden auch auf dem Datenbankserver Ressourcen für die Verbindung reserviert, die nicht freigegeben werden, wenn das Connection-Objekt nur aufgegeben, aber noch nicht vom Garbage Collector bereinigt wird. Sie sollten daher immer so schnell wie möglich eine geöffnete Verbindung durch Aufruf der Close-Methode auf das Connection-Objekt wieder schließen.
| ...
|
| con.Open();
|
| // Anweisungen
|
| con.Close();
|
26.2.5 Die Dauer des Verbindungsaufbaus
 
Standardmäßig wird 15 Sekunden lang versucht, die Verbindung erfolgreich aufzubauen. Verstreicht diese Zeit, ohne dass der Datenbankserver erreicht wird, wird eine Ausnahme ausgelöst. Äußere Umstände wie die Netzwerk- oder Serverbelastung können dazu führen, dass diese Zeitspanne unter Berücksichtigung aller Umstände zu knapp bemessen ist. In der Verbindungszeichenfolge kann daher mit Hilfe des Attributs Connect Timeout (bzw. Connection Timeout) eine andere Zeitspanne eingestellt werden. Die Angabe erfolgt in Sekunden, z.B.:
| SqlConnection con = new SqlConnection("Data Source=localhost;" +
|
| "Initial Catalog=pubs;Connect Timeout=30;" +
|
| "Trusted_Connection=yes");
|
Das Connection-Objekt verfügt auch über eine Eigenschaft ConnectionTimeout, die allerdings schreibgeschützt ist. Ihr kann daher auch keine vom Standard abweichende Zeitspanne zugewiesen werden.
26.2.6 Eigenschaften eines »Connection«-Objekts
 
Neben der bereits behandelten Eigenschaft ConnectionString veröffentlichen die Connection-Klassen noch weitere Eigenschaften und Methoden. Wir wollen uns diese jetzt ansehen. Einige davon sind providerspezifisch.
Tabelle 26.2 Die Eigenschaften eines »SqlConnection«-Objekts
| Eigenschaft
|
Beschreibung
|
| ConnectionString
|
Enthält alle Informationen zum Verbindungsaufbau.
|
| ConnectionTimeout
|
(schreibgeschützt) Ruft die Zeitspanne ab, die dem Versuch zum Aufbau der Verbindung zu einer Datenquelle zugestanden wird. Zu beachten ist, dass nicht alle Datenbanken dieses Feature unterstützen.
|
| Database
|
(schreibgeschützt) Bei Datenquellen, die mehrere Datenbanken unterstützen (z.B. SQL Server), liefert diese Eigenschaft den Namen der Datenbank.
|
| DataSource
|
(schreibgeschützt) Bei dateibasierten Datenbanken (z.B. MS Access) liefert diese Eigenschaft den Pfad zur Datenbank, bei serverbasierten Datenquellen den Namen des Rechners, auf dem der Server installiert ist.
|
| PacketSize
|
(schreibgeschützt, nur SqlConnection) Gibt die verwendete Paketgröße für die Kommunikation mit dem Datenbankserver über das Netzwerk zurück.
|
| ServerVersion
|
(schreibgeschützt) Liefert die Versionsnummer des verwendeten Servers. Das Abrufen dieser Eigenschaft ist beispielsweise dann sinnvoll, wenn ein bestimmtes Feature erst ab einer bestimmten Version zur Verfügung steht.
|
| State
|
(schreibgeschützt) Beschreibt den aktuellen Zustand der Verbindung.
|
| WorkstationID
|
(schreibgeschützt, nur SqlConnection) Gibt den Netzwerknamen des Client-Rechners zurück.
|
Bis auf die Eigenschaft ConnectionString sind alle anderen schreibgeschützt und liefern größtenteils nur die Werte zurück, die der Verbindungszeichenfolge über die Attribute übergeben werden.
26.2.7 Die Ereignisse eines »Connection«-Objekts
 
Mit InfoMessage und StateChange besitzt das Connection-Objekt nur zwei Ereignisse.
Das Ereignis »InfoMessage«
Bei auftretenden Problemen gibt der SQL Server eine Informationsmeldung an den Aufrufer zurück, die das Problem beschreibt. Ein Problem kann mehr oder weniger schwerwiegend sein. Um es genauer zu beschreiben, unterscheidet der SQL Server Fehler in ihrem Schweregrad und definiert dazu 25 Stufen. Der Schweregrad 0 bis 10 steht ausschließlich für Informationsmeldungen zur Verfügung. Fehler des Schweregrads 11 bis 16 kann ein Anwender selbst beheben, ab Schweregrad 17 muss der Datenbankadministrator aktiv werden.
Das InfoMessage-Ereignis wird ausgelöst, wenn vom SQL Server eine Meldung mit einem Schweregrad von 10 oder weniger zurückgegeben wird.
Das Ereignis »StateChange«
StateChange tritt auf, wenn sich die State-Eigenschaft ändert, die den aktuellen Zustand der Verbindung beschreibt. Im Ereignishandler können Sie die Eigenschaften OriginalState und CurrentState des Args-Objekts auswerten, um den alten und neuen Zustand der Verbindung zu überprüfen.
| class Program {
|
| static void Main(string[] args) {
|
| ...
|
| con.StateChange += new StateChangeEventHandler(con_StateChange);
|
| con.Open();
|
| con.Close();
|
| Console.ReadLine();
|
| }
|
| static void con_StateChange(object obj, StateChangeEventArgs e) {
|
| Console.Write("Zustand: von {0}", e.OriginalState.ToString());
|
| Console.WriteLine(" nach {0}", e.CurrentState.ToString());
|
| }
|
| }
|
26.2.8 Unterstützung bei Projekten mit grafischer Benutzeroberfläche
 
Sie wissen jetzt, wie Sie mittels Code die Verbindung zu einer Datenquelle herstellen können. Entwickeln Sie eine Konsolenanwendung, müssen Sie so verfahren, wie es die letzten Abschnitte gezeigt haben. Einfacher wird es, wenn Sie eine Anwendung mit grafischer Benutzeroberfläche erstellen, z.B. eine Windows-Anwendung oder eine ASP.NET-Webanwendung. Anwendungen mit einer GUI-Schnittstelle genießen den Vorzug, dass die Entwicklungsumgebung des Visual Studio 2005 dem Designer mehrere Features zur Verfügung stellt, die mit ihrem Automatismus deutlich zur Vereinfachung der Programmierung beitragen. An dieser Stelle möchte ich Ihnen zunächst das zur Aufnahme einer Verbindung zu einer Datenquelle vorstellen. Andere Tools werden an späterer Stelle noch folgen.
Eine Verbindung mit einem Steuerelement herstellen
Um eine Verbindung zu einer Datenbank herzustellen, können Sie das SqlConnection-Steuerelement benutzen, das Sie allerdings zuvor der Toolbox hinzufügen müssen. Ziehen Sie in bekannter Weise das gewünschte Steuerelement in den aktiven Designer, wird es im Komponentenfach abgelegt. Danach muss die Verbindungszeichenfolge festgelegt werden. Markieren Sie dazu im Eigenschaftsfenster die Eigenschaft ConnectionString, und klicken Sie in der Wertespalte auf die Schaltfläche mit dem nach unten zeigenden Pfeil. Es öffnet sich ein kleines Auswahlfenster, in dem Sie den Eintrag <Neue Verbindung...> finden. Klicken Sie darauf, sehen Sie den Dialog Verbindung hinzufügen. Tragen Sie hier den Server ein, geben dann die Authentifizierungsdaten an und wählen die Datenbank aus, auf deren Daten Sie zugreifen möchten. Sie können sogar noch die Verbindung abschließend testen.
 Hier klicken, um das Bild zu vergrößern
Abbildung 26.1 Dialog zum Aufbau einer Datenbankverbindung
| Hinweis Sollten die Beispielprogramme, die sich auf der Buch-CD befinden, auf Ihrem Rechner nicht funktionieren, sollten Sie sich die Verbindungszeichenfolge ansehen und entsprechend anpassen.
|
|